/**
 * @Author: 十三
 * @Date: 2023-16-28 04:13:08
 * @email: 2429120006@qq.com
 * @Description: oss文件上传
 */
// @ts-ignore
import OSS from 'ali-oss';
// import { toFixedFix } from 'co-utils-vue';
import { isFunction } from 'lodash-es';

import type { IOssData } from '@/api/oss/type';
import { useUserStore } from '@/hooks/store/auth';

export interface ISuccess {
    url: string;
    size: number;
    name: string;
}

export interface IProgress {
    progress: number;
    name: string;
}

export interface IOssUpload {
    files: File;
    type?: 'file' | 'image' | 'avatar' | 'cover' | 'default';
    UUID?: boolean;
    success?: (res: ISuccess) => void;
    progress?: (progress: IProgress) => void;
    stsToken?: Omit<IOssData, 'userInfo'>;
}

// const getGenerate#stsToken = async () => {
//   const res = ;
//   return useOmit(res, ['userInfo']);
// };
const handleCheckOss = (value: IOssUpload['stsToken']) => {
  return new Promise((resolve, reject) => {
    if (!value || Object.values(value).some(v => v === '')) {
      reject('校验OSS配置为空，无法上传');
    }
    resolve(true);
  });
};

/**
 * 上传实例
 */
export class AliOssUpload {
  client: OSS | null;

  #userStore: any;

  #stsToken: IOssUpload['stsToken'];

  #type: IOssUpload['type'];

  #UUID: IOssUpload['UUID'];

  constructor(params?: IOssUpload['stsToken']) {
    this.client = null;
    this.#userStore = useUserStore();
    if (params) {
      this.#stsToken = params;
      this.init();
    }
  }

  /**
     * 设置#stsToken
     * @param token
     * @private
     */
  public setStsToken(token?: IOssUpload['stsToken']) {
    const self = this;
    return new Promise((resolve, reject) => {
      if (!token) {
        this.#userStore.getStsToken().then((res: IOssUpload['stsToken']) => {
          handleCheckOss(res).then(() => {
            self.#stsToken = res;
            self.init();
            resolve('上传配置成功');
          }).catch(error => {
            reject(error);
          });
        }).catch(() => {
          reject('获取STS令牌失败！');
        });
      } else {
        self.#stsToken = token;
        self.init();
        resolve('上传配置成功');
      }
    });
  }

  /**
     * 单个上传方法
     * @param file 上传的文件
     * @param path 上传路径
     * @param success 成功回调
     * @param progress 进度回调
     * @private
     */
  public upload(
    file: File,
    path?: IOssUpload['type'],
    success?: IOssUpload['success'] | null,
    progress?: IOssUpload['progress']
  ): Promise<ISuccess> {
    const PATH = `${this.#userStore.userInfo.account}/${path || 'default'}/${file.name}`;
    const self = this;
    return new Promise((resolve, reject) => {
      if (!self.#stsToken) reject('请先配置OSS');
      handleCheckOss(this.#stsToken!).catch(e => {
        reject(e);
      });
      this.client?.multipartUpload(PATH, file, {
        progress: (p: number) => {
          if (isFunction(progress)) {
            progress({
              progress: Math.floor(p * 100).toFixed(2),
              name: file.name
            });
          }
        },
        partSize: 2 * 1024 * 1024
      }).then((res: any) => {
        if (isFunction(success)) {
          success({
            url: res.res.requestUrls[0].split('?uploadId')[0],
            name: file.name.split('.')[0],
            size: file.size
          });
        }
        resolve({
          url: res.res.requestUrls[0].split('?uploadId')[0],
          name: file.name.split('.')[0],
          size: file.size
        });
      }).catch((e: any) => {
        reject(e);
      });
    });
  }

  /**
     * 批量上传
     * @param files
     * @param path
     * @param progress
     * @private
     */
  public async batchUpload(
    files: File[],
    path?: IOssUpload['type'],
    progress?: IOssUpload['progress']
  ) {
    const uploadTask = files.map(file => this.upload(file, path, null, progress));
    const uploadRes = await Promise.all(uploadTask);
    return uploadRes;
  }

  public init() {
    console.log(33, this.#stsToken);
    this.client = new OSS({
      endpoint: this.#stsToken?.endpoint,
      accessKeyId: this.#stsToken?.accessKeyId!,
      accessKeySecret: this.#stsToken?.accessKeySecret!,
      stsToken: this.#stsToken?.securityToken,
      bucket: this.#stsToken?.bucket,
      secure: true,
      // @ts-ignore
      useFetch: true, // 支持上传大于100KB的文件
      cname: this.#stsToken?.cname === 1
    });
  }
}
